Semaphores are utilized to manage and synchronize shared resources of computer-based systems such as data storage resources. Typically, a semaphore will have a semaphore counter representative of the number or amount of a resource that is available. In some systems, resource consuming threads will cause the semaphore-counter to decrement when a resource is available and allocated. If the current counter value is smaller than the required quantity needed by the thread, the thread will be added to a waiting queue and may be suspended until the resource is available.
In some systems, a control thread (e.g., which may be used to allocate resources) changes properties of the semaphore and associated resources (e.g., such as their availability due to some system policy) and decrementing the semaphore counter. A control thread will typically accomplish decreasing the resource quantity by executing a standard semaphore decrement operation. This approach can be problematic because it potentially involves blocking the control thread and forcing it to wait for resource consuming threads to finish utilizing the resources. For example, if the semaphore counter reflects zero available resources, the semaphore counter cannot be decremented until it first equals a value greater than zero. Table 1 below shows an exemplary series of events utilizing a traditional semaphore.
TABLE 1ConcurrentlyAvailableSemaphoreUsed ResourcesResourcesCountQueueEvent03301220Request Resource2110Request Resource3000Request Resource3001Request Resource3002Request Resource3001Release Resource3002Request Resource3003Control Thread Decrement3002Release Resource3001Release Resource2001Request Resource2000Release Resource1110Release Resource0220Release Resource0330Control Thread Increment
In some systems the semaphore is used as a gate to a working queue, and the semaphore counter reflects the number of resources that must be utilized before a particular operation is performed by a working thread (e.g., a batch write operation). In some systems, multiple control threads may decrement the semaphore counter to reduce the number of available resources and/or remove entries from the working queue. In some cases, multiple control threads (e.g., an I/O control thread and a cache control thread) may be working together to manage resources (e.g., size of batch writes from a cache resource).
In some systems, decrementing the semaphore and removing an entry from a working queue (by the control threads) may not be an atomic operation, and may result a “double decrement” for a period of time before consistency in the semaphore is recovered. In this case, consistency in the semaphore is recovered by incrementing the semaphore counter. However, if the semaphore counter is zero during the process of double decrementing, the control thread (e.g., I/O control thread) will have to wait for worker threads to release allocated resources before the control threads have an opportunity to manage and correct the semaphore counter.